package org.finesys.quartz.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import org.finesys.common.core.module.R;
import org.finesys.common.mp.core.service.impl.BaseServiceImpl;
import org.finesys.common.quartz.core.constants.JobStatusEnum;
import org.finesys.quartz.entity.SysJob;
import org.finesys.quartz.mapper.SysJobMapper;
import org.finesys.quartz.service.SysJobService;
import org.finesys.quartz.support.JobScheduler;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import cn.hutool.core.util.ArrayUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@RequiredArgsConstructor
@Slf4j
public class SysJobServiceImpl extends BaseServiceImpl<SysJobMapper, SysJob> implements SysJobService {

    private final JobScheduler jobScheduler;
    private final SysJobMapper sysJobMapper;

    @Override
    public R<?> addJob(SysJob sysJob) {
        //检查组内名称是否相同
        SysJob exsitsJobName = sysJobMapper.selectOne(Wrappers.<SysJob>lambdaQuery().eq(SysJob::getJobName, sysJob.getJobName()).eq(SysJob::getJobGroup, sysJob.getJobGroup()));
        if (Objects.nonNull(exsitsJobName)) {
            return R.failed("任务重复，请检查此组内是否已包含同名任务");
        }
        sysJobMapper.insert(sysJob);
        return R.success();
    }

    @Override
    public R<?> updateJob(SysJob sysJob) {
        //获取原来的job
        SysJob oldSysJob = sysJobMapper.selectById(sysJob.getJobId());
        //判断状态
        //已发布状态，直接更新数据
        if (JobStatusEnum.RELEASE.getValue().equals(oldSysJob.getJobStatus())) {
            //直接更新数据即可
        } else if (JobStatusEnum.RUNNING.getValue().equals(oldSysJob.getJobStatus())) {
            //运行中，需要先删除，在重新执行
            //暂停的需要修改
            if (jobScheduler.exsitsJob(sysJob)) {
                //更新job信息
                jobScheduler.update(sysJob);
            }
        } else if (JobStatusEnum.PAUSE.getValue().equals(oldSysJob.getJobStatus())) {
            //暂停的需要修改
            if (jobScheduler.exsitsJob(sysJob)) {
                //更新job信息
                jobScheduler.update(sysJob);
                //暂停任务执行
                jobScheduler.pause(sysJob);
            }
        } else {
            //暂停的需要修改
            if (jobScheduler.exsitsJob(sysJob)) {
                //删除job信息
                jobScheduler.delete(sysJob);
            }
        }
        sysJobMapper.updateById(sysJob);
        return R.success();
    }

    @Override
    public R<?> deleteJob(Long[] jobIds) {
        //获取数据
        List<SysJob> sysJobList = sysJobMapper.selectBatchIds(Arrays.asList(jobIds));
        sysJobList.stream().forEach(sysJob -> {
            //发布和删除状态无需判断是否存在任务
            if (JobStatusEnum.RELEASE.getValue().equals(sysJob.getJobStatus()) ||
                    JobStatusEnum.DELETE.getValue().equals(sysJob.getJobStatus())) {
                return;
            }
            //判断是否存在job并删除
            if (jobScheduler.exsitsJob(sysJob)) {
                //删除job信息
                jobScheduler.delete(sysJob);
            }
        });
        sysJobMapper.deleteBatchIds(Arrays.asList(jobIds));
        return R.success();
    }

    @Override
    public R<?> startAll() {
        // 恢复所有暂停的任务为启动
        jobScheduler.startAll();
        // 更新定时任务状态条件，暂停状态3更新为运行状态2
        sysJobMapper.update(SysJob.builder().jobStatus(JobStatusEnum.RUNNING.getValue()).build(), new UpdateWrapper<SysJob>().lambda().eq(SysJob::getJobStatus, JobStatusEnum.PAUSE.getValue()));
        return R.success();
    }

    @Override
    public R<?> stopAll() {
        // 暂停所有的任务
        jobScheduler.stopAll();
        long count = sysJobMapper.selectCount(
                new LambdaQueryWrapper<SysJob>().eq(SysJob::getJobStatus, JobStatusEnum.RUNNING.getValue()));
        if (count <= 0) {
            return R.success("无正在运行定时任务");
        }
        // 更新定时任务状态条件，暂停状态3更新为运行状态2
        sysJobMapper.update(SysJob.builder().jobStatus(JobStatusEnum.PAUSE.getValue()).build(), new UpdateWrapper<SysJob>().lambda().eq(SysJob::getJobStatus, JobStatusEnum.RUNNING.getValue()));
        return R.success();
    }

    @Override
    public R<?> start(Long[] jobIds) {
        List<SysJob> sysJobList = sysJobMapper.selectBatchIds(Arrays.asList(jobIds));
        if (ArrayUtil.isEmpty(sysJobList)) {
            return R.failed("不存在定时任务，请确认！");
        }
        //启动任务
        sysJobList.stream().forEach(sysJob -> {
            // 如果定时任务不存在，强制状态为1已发布
            if (!jobScheduler.exsitsJob(sysJob)) {
                sysJob.setJobStatus(JobStatusEnum.RELEASE.getValue());
            }
            //启动定时任务
            if (JobStatusEnum.RELEASE.getValue().equals(sysJob.getJobStatus())) {
                jobScheduler.add(sysJob);
            } else {
                jobScheduler.resume(sysJob);
            }
            //更新状态
            sysJobMapper.updateById(SysJob.builder().jobId(sysJob.getJobId()).jobStatus(JobStatusEnum.RUNNING.getValue()).build());
        });
        return R.success();
    }

    @Override
    public R<?> stop(Long[] jobIds) {
        //只查询运行中的状态
        List<SysJob> sysJobList = sysJobMapper.selectList(Wrappers.<SysJob>lambdaQuery().eq(SysJob::getJobStatus, JobStatusEnum.RUNNING.getValue()).in(SysJob::getJobId, Arrays.asList(jobIds)));
        if (ArrayUtil.isEmpty(sysJobList)) {
            return R.failed("不存在定时任务，请确认！");
        }
        //暂停任务
        sysJobList.stream().forEach(sysJob -> {
            //暂停定时任务
            jobScheduler.pause(sysJob);
            //更新状态
            sysJobMapper.updateById(SysJob.builder().jobId(sysJob.getJobId()).jobStatus(JobStatusEnum.PAUSE.getValue()).build());
        });
        return R.success();
    }

    @Override
    public R<?> run(Long[] jobIds) {
        List<SysJob> sysJobList = sysJobMapper.selectBatchIds(Arrays.asList(jobIds));
        if (ArrayUtil.isEmpty(sysJobList)) {
            return R.failed("不存在定时任务，请确认！");
        }
        //启动任务
        sysJobList.stream().forEach(sysJob -> {
            //启动定时任务
            if (JobStatusEnum.RELEASE.getValue().equals(sysJob.getJobStatus())) {
                jobScheduler.add(sysJob);
            } else if (JobStatusEnum.PAUSE.getValue().equals(sysJob.getJobStatus())) {
                jobScheduler.resume(sysJob);
            } else {
                return;
            }
            //更新状态
            sysJobMapper.updateById(SysJob.builder().jobId(sysJob.getJobId()).jobStatus(JobStatusEnum.RUNNING.getValue()).build());
        });
        return R.success();
    }

    @Override
    public R<?> refreshJob() {
        List<SysJob> sysJobList = sysJobMapper.selectList(Wrappers.emptyWrapper());
        if (ArrayUtil.isEmpty(sysJobList)) {
            return R.failed("不存在定时任务，请确认！");
        }
        //启动任务
        sysJobList.stream().forEach(sysJob -> {
            //启动定时任务
            if (JobStatusEnum.RELEASE.getValue().equals(sysJob.getJobStatus())) {
                if (jobScheduler.exsitsJob(sysJob)) {
                    jobScheduler.delete(sysJob);
                }
            } else if (JobStatusEnum.RUNNING.getValue().equals(sysJob.getJobStatus())) {
                jobScheduler.update(sysJob);
            } else if (JobStatusEnum.PAUSE.getValue().equals(sysJob.getJobStatus())) {
                jobScheduler.update(sysJob);
                jobScheduler.pause(sysJob);
            } else {
                jobScheduler.delete(sysJob);
            }
        });
        return R.success();
    }
}
